<template>
    <div  class="at-popover" v-if="visible" id="at-popover" :style="{...positionStyle}">
        <div class="at-popover-content" ref="atPopoverContent">
            <ul>
                <li v-for="(item,index) in list" :key="index"  class="at-popover-line" :class="{active:index===activeLine}" @click="handleSelect(item.name)">
                    <div v-if="item.avatar" class="at-popover-line-avatar-wrap">
                        <img :src="item.avatar" alt="" class="at-popover-line-avatar"> 
                    </div>
                    <div>
                        {{item.name}}
                    </div>
                </li>
            </ul>
        </div>
    </div>
</template>
<script setup lang="ts">
import { withDefaults,ref,watch,computed,nextTick } from 'vue';
import type {InlineStyles,AtEachMember} from "./types/index"
const props=withDefaults(defineProps<{
    visible:boolean
    list:AtEachMember[]
}>(),{
    visible:false
});

// 当前选中@
const activeLine=ref(0);
// 父组件确定方法
const emits=defineEmits(['confirm'])
// 选中的人
const handleSelect=(name:string)=>{
    emits("confirm",name)
}

// 容器
const atPopoverContent=ref<HTMLElement|null>(null)

// 容器的高度
const atPopoverContentHeight=ref(0)

// 每一行的高度
const atPopoverLineHeight=computed(()=>{
    return document.querySelector(".at-popover-line")?.clientHeight||0
})

// 处理键盘上下键长度较长滚动
const handleKeyScrollContainer=()=>{
    // 多少时会超出范围
    const maxShowNum=Math.floor(atPopoverContentHeight.value/atPopoverLineHeight.value)
    if(activeLine.value>=maxShowNum-1){
        atPopoverContent.value?.scrollTo(0,(activeLine.value-maxShowNum+2)*atPopoverLineHeight.value)
    }
    else{
        atPopoverContent.value?.scrollTo(0,0)
    }
}

// @功能上下键切换
const handleKeyUp = (e:KeyboardEvent) => {
  if (props.visible) {
    // 下键
    if (e.keyCode === 40) {
        handleKeyScrollContainer()
        activeLine.value=Math.min(activeLine.value+1,props.list.length-1)
    }
    // 上键 
    else if (e.keyCode === 38) {
        handleKeyScrollContainer()
        activeLine.value=Math.max(activeLine.value-1,0)
    }
    // 回车键 
    else if (e.keyCode === 13) {
       handleSelect(props.list[activeLine.value].name)
    }
  }
};

watch(()=>props.visible,(newVal)=>{
    if(newVal){
        activeLine.value=0;
        document.addEventListener("keyup", handleKeyUp);
    }
    else{
        document.removeEventListener("keyup", handleKeyUp);
    }
})

watch(()=>[props.list.length,props.visible,atPopoverContent.value],([newVal1,newVal2,newVal3])=>{
    if([newVal1,newVal2,newVal3].some(item=>item)){
        activeLine.value=0;
        nextTick(()=>{
            atPopoverContentHeight.value=atPopoverContent.value?.clientHeight||0
            changePosition()
        })
    }
},{
    deep:true
})

// 改变popover弹出的位置
// 位置样式
const positionStyle=ref<InlineStyles>({})
// 改变位置样式
const changePosition = () => {
    nextTick(()=>{
        if(window&&window.getSelection()){
            const sel= window.getSelection() as Selection;
            let range = sel.getRangeAt(0); // 获取当前光标
            let position = range.getBoundingClientRect(); // 获取标签位置
            const {x,y}=position;
            positionStyle.value = {
                top: y-atPopoverContentHeight.value + "px",
                left: x + "px",
            };
        }
    })
};

</script>
<style scoped>
.at-popover {
    display: block; /* 默认隐藏 */
    position: fixed;
    background-color: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.3);
    top:-200px;
    left:0;
}

.at-popover-line{
    display: flex;
    align-items: center;
    cursor: pointer;
    padding: 5px 10px;
}

.at-popover-content{
    max-height: 200px;
    overflow: auto;
}

.at-popover-content::-webkit-scrollbar {
    display: none;
}
.at-popover-line-avatar-wrap{
    margin-right: 5px;
    height:20px;
}
.at-popover-line-avatar{
    width:20px;
    height:20px;
}

.at-popover-line:hover{
    background-color: #f1f1f1;
}

.active{
    background-color: #f1f1f1;
}
</style>